#include "zy_light_sensor.h"
#include "adi1787.h"
#include "ps.h"

#include "headset_sm.h"
#include "ui_inputs.h"
#include "ui.h"
#include "adk_log.h"

#ifdef Enable_Light_Sensor
LightSensorTaskData light_sensor_tast;
uint8 wear_state = 1;
uint8 anc_state_tmp;
uint8 music_paused_by_light = 0;
uint32 wearless_time = 0;
static Task hs_task;

static void Light_Sensor_Detect_handler(Task task, MessageId id, Message msg)
{
    UNUSED(task);
    UNUSED(msg);
    switch (id)
    {
    case EventLSDetectOFFLED:
        DEBUG_LOG_V_VERBOSE("EventLSDetectOFFLED!");
        Light_Sensor_Detect_OFFLED();
        break;
    case EventLSDetectONLED:
        DEBUG_LOG_V_VERBOSE("EventLSDetectONLED!");
        Light_Sensor_Detect_ONLED();
        break;
    case EventLSDetectOFFLEDRecheck:
        DEBUG_LOG_V_VERBOSE("EventLSDetectOFFLEDRecheck!");
        Light_Sensor_Detect_OFFLED_Recheck();
        break;
    case EventLSMusicPause:
        Ui_InjectUiInput(ui_input_pause);
        break;
    case EventLSMusicPlay:
        Ui_InjectUiInput(ui_input_play);
        break;
    default:
        break;
    }
}

/* 灭灯检查 */
void Light_Sensor_Detect_OFFLED(void) //EventLSDetectOFFLED
{
    MessageCancelAll(LightSensorGetTask(), EventLSDetectOFFLED);
    if ((PioGet32Bank(0) & WEAR_RESULT_PIN)) //未佩戴
    {
        DEBUG_LOG_V_VERBOSE("Detect_OFFLED: no wear");
        if (wear_state) //判断是否有佩戴变化
        {
            No_Wear_State_Operate();
        }
        else
        {
            wearless_time++;
            if (wearless_time > 600) //未佩戴时长超过10分钟,执行关机
            {
                wearless_time = 0;
                Ui_InjectUiInput(ui_input_sm_power_off);
            }
        }
        MessageSendLater(LightSensorGetTask(), EventLSDetectOFFLED, 0, 1000);
    }
    else
    {
        DEBUG_LOG_V_VERBOSE("Detect_OFFLED: wear");
        /* result pin低，佩戴状态不确定，启动1ms后开灯检测 */
        PioSetDir32Bank(0, WEAR_DETECT_PIN, WEAR_DETECT_PIN); //设置GPIO输出模式
        PioSet32Bank(0, WEAR_DETECT_PIN, 0);                  //拉低GPIO
        MessageSendLater(LightSensorGetTask(), EventLSDetectONLED, 0, 1);
    }
}

/* 亮灯检查 */
void Light_Sensor_Detect_ONLED(void) //EventLSDetectONLED
{
    if ((PioGet32Bank(0) & WEAR_RESULT_PIN)) //检测到佩戴
    {
        DEBUG_LOG_V_VERBOSE("Detect_ONLED: wear");
        /* 重置佩戴传感器，5ms后重新灭灯检查 */
        PioSetDir32Bank(0, WEAR_DETECT_PIN, 0);
        PioSet32Bank(0, WEAR_DETECT_PIN, 0);
        PioSetStrongBias32Bank(0, WEAR_DETECT_PIN, 0);
        MessageCancelAll(LightSensorGetTask(), EventLSDetectOFFLEDRecheck);
        MessageSendLater(LightSensorGetTask(), EventLSDetectOFFLEDRecheck, 0, 10);
    }
    else //检测到未佩戴
    {
        DEBUG_LOG_V_VERBOSE("Detect_ONLED: no wear");
        if (wear_state) //判断是否有佩戴变化
        {
            No_Wear_State_Operate();
        }
        else
        {
            wearless_time++;
            if (wearless_time > 600) //未佩戴时长超过10分钟,执行关机
            {
                Ui_InjectUiInput(ui_input_sm_power_off);
            }
        }
        /* 重置佩戴传感器，1s后开启下一轮检测 */
        PioSetDir32Bank(0, WEAR_DETECT_PIN, 0);
        PioSet32Bank(0, WEAR_DETECT_PIN, 0);
        PioSetStrongBias32Bank(0, WEAR_DETECT_PIN, 0);
        MessageCancelAll(LightSensorGetTask(), EventLSDetectONLED);
        MessageSendLater(LightSensorGetTask(), EventLSDetectOFFLED, 0, 1000);
    }
}

/* 亮灯检测佩戴后，重复灭灯检查 */
void Light_Sensor_Detect_OFFLED_Recheck(void)
{
    if ((PioGet32Bank(0) & WEAR_RESULT_PIN)) //pin高，佩戴重复验证失败
    {
        DEBUG_LOG_V_VERBOSE("Detect_OFFLED_Recheck: no wear");
        if (wear_state) //判断是否有佩戴变化
        {
            No_Wear_State_Operate();
        }
        else
        {
            wearless_time++;
            if (wearless_time > 600) //未佩戴时长超过10分钟,执行关机
            {
                Ui_InjectUiInput(ui_input_sm_power_off);
            }
        }
    }
    else //pin低，确认佩戴
    {
        DEBUG_LOG_V_VERBOSE("Detect_OFFLED_Recheck: wear");
        if (!wear_state) //判断是否有佩戴变化
        {
            Wear_State_Operate();
        }
        wearless_time = 0;
    }
    MessageCancelAll(LightSensorGetTask(), EventLSDetectONLED);
    MessageSendLater(LightSensorGetTask(), EventLSDetectOFFLED, 0, 1000);
}

/* 执行佩戴状态切换 */
void Wear_State_Operate(void)
{
    uint8 response[3] = {0x0b, 0x0a, 0x00}; /* GAIA发送ANC实时状态 0：OFF,1：ON, 2：ambient sound */
    DEBUG_LOG_V_VERBOSE("Wear_State_Operate headset_sm.state:%d music_paused_by_light:%d", headset_sm.state, music_paused_by_light);
    if (((headset_sm.state == HEADSET_STATE_IDLE) || (headset_sm.state == HEADSET_STATE_BUSY)) && music_paused_by_light)
    {
        music_paused_by_light = 0;
        MessageSendLater(LightSensorGetTask(), EventLSMusicPlay, 0, 1800);
    }
    /* ANC状态调整 */
    if ((anc_state == STATE_ANC_OFF) && (anc_state_tmp != STATE_ANC_OFF))
    {
        if (anc_is_changing)
        {
            /* 不进行操作 */
        }
        else
        {
            anc_is_changing = 1;
            wear_state = 1;
            if (anc_state_tmp == STATE_ANC_ON)
            {
                ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_ADC_DAC_POWER, 1, ADC_POWER_ON);   //ADC power on
                ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_MBIAS_PGA_POWER, 1, MBIAS_PGA_ON); //MBIAS PGA power on
                ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_ADC_MUTE_REG, 1, ADC_UNMUTE);      //ADC Unmuted
                ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_BANK_CONTROL_REG, 1, BANK_A);      //BANK A
                MessageCancelAll(AncGetTask(), EventMyAncOnExeture);
                MessageSendLater(AncGetTask(), EventMyAncOnExeture, 0, anc_prompt_time);
                response[2] = 1;
            }
            else if (anc_state_tmp == STATE_MONITOR_ON)
            {
                ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_ADC_DAC_POWER, 1, ADC_POWER_ON);   //ADC power on
                ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_MBIAS_PGA_POWER, 1, MBIAS_PGA_ON); //MBIAS PGA power on
                ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_ADC_MUTE_REG, 1, ADC_UNMUTE);      //ADC Unmuted
                ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_BANK_CONTROL_REG, 1, BANK_B);      //BANK B
                MessageCancelAll(AncGetTask(), EventMyMonitorOnExeture);
                MessageSendLater(AncGetTask(), EventMyMonitorOnExeture, 0, anc_prompt_time);
                response[2] = 2;
            }
            else
            {
                anc_is_changing = 0;
            }
            GaiaSendPacket(gaia_get_transport(), GAIA_VENDOR_QTIL, GAIA_EVENT_NOTIFICATION, GAIA_STATUS_NONE, 3, response);
        }
    }
    else
    {
        wear_state = 1;
    }
}

/* 执行未佩戴状态切换 */
void No_Wear_State_Operate(void)
{
    uint8 response[3] = {0x0b, 0x0a, 0x00}; /* GAIA发送ANC实时状态 0：OFF,1：ON, 2：ambient sound */
    if (!anc_is_changing)
    {
        if (headset_sm.state == HEADSET_STATE_BUSY)
        {
            music_paused_by_light = 1;
            Ui_InjectUiInput(ui_input_pause);
        }
        anc_state_tmp = anc_state;
        anc_is_changing = 1;
        Enter_IIS_Only();
        wear_state = 0;
        GaiaSendPacket(gaia_get_transport(), GAIA_VENDOR_QTIL, GAIA_EVENT_NOTIFICATION, GAIA_STATUS_NONE, 3, response);
    }
    else
    {
        /* 等待上一个ANC状态调整完成 */
    }
}

void Light_Sensor_Init(Task init_task)
{
    uint16 ret_len;
    uint16 requested_words;
    uint16 light_sensor_endabled;
    LightSensorTaskData *theuser = LightSensorGetTaskData();
    requested_words = PS_SIZE_ADJ(sizeof(uint16));
    ret_len = PsRetrieve(light_sensor_enabled_key, NULL, 0);
    if (!ret_len) /* 系统第一次上电，默认开启佩戴传感器并保存pskey */
    {
        light_sensor_endabled = 1;
        PsStore(light_sensor_enabled_key, (const uint16 *)&light_sensor_endabled, requested_words);
    }
    else
    {
        PsRetrieve(light_sensor_enabled_key, &light_sensor_endabled, requested_words);
    }
    if (light_sensor_endabled)
    {
        /* 初始化任务 */
        hs_task = init_task;
        memset(theuser, 0, sizeof(*theuser));
        theuser->task.handler = Light_Sensor_Detect_handler;

        music_paused_by_light = 0;
        /* 重置佩戴传感器，1s后开启下一轮检测 */
        PioSetMapPins32Bank(0, WEAR_DETECT_PIN, WEAR_DETECT_PIN);
        PioSetDir32Bank(0, WEAR_DETECT_PIN, 0);
        PioSet32Bank(0, WEAR_DETECT_PIN, 0);
        PioSetStrongBias32Bank(0, WEAR_DETECT_PIN, 0);

        PioSetMapPins32Bank(0, WEAR_RESULT_PIN, WEAR_RESULT_PIN);
        PioSetDir32Bank(0, WEAR_RESULT_PIN, 0);        //设置GPIO输入模式
        PioSet32Bank(0, WEAR_RESULT_PIN, 0);           //设置下拉
        PioSetStrongBias32Bank(0, WEAR_RESULT_PIN, 0); //设置高阻

        /* 开机10秒后启动光感检测，1s检测一次*/
        wearless_time = 0;
        wear_state = 1;
        MessageCancelAll(LightSensorGetTask(), EventLSDetectOFFLED);
        MessageCancelAll(LightSensorGetTask(), EventLSDetectONLED);
        MessageSendLater(LightSensorGetTask(), EventLSDetectOFFLED, 0, 10000);
    }
}

void Light_Sensor_DeInit(void)
{
    MessageCancelAll(LightSensorGetTask(), EventLSDetectOFFLED);
    MessageCancelAll(LightSensorGetTask(), EventLSDetectONLED);
    PioSetDir32Bank(0, WEAR_RESULT_PIN | WEAR_DETECT_PIN, 0);        //设置GPIO输入模式
    PioSet32Bank(0, WEAR_RESULT_PIN | WEAR_DETECT_PIN, 0);           //设置下拉
    PioSetStrongBias32Bank(0, WEAR_RESULT_PIN | WEAR_DETECT_PIN, 0); //设置高阻
}
#endif
/* adi1787库控制佩戴传感器回调函数 */
void set_light_sensor_enabled(bool mode)
{
#ifdef Enable_Light_Sensor
    uint16 light_sensor_endabled;
    uint16 requested_words;
    requested_words = PS_SIZE_ADJ(sizeof(uint16));
    if (mode)
    {
        light_sensor_endabled = 1;
        PsStore(light_sensor_enabled_key, (const uint16 *)&light_sensor_endabled, requested_words);
        Light_Sensor_Init(hs_task);
    }
    else
    {
        light_sensor_endabled = 0;
        PsStore(light_sensor_enabled_key, (const uint16 *)&light_sensor_endabled, requested_words);
        Light_Sensor_DeInit();
    }
#else
    UNUSED(mode);
#endif
}

/* adi1787库控制佩戴传感器回调函数 */
bool get_light_sensor_enabled(void)
{
#ifdef Enable_Light_Sensor
    uint16 requested_words, ret_len, ret;
    requested_words = PS_SIZE_ADJ(sizeof(uint16));
    ret_len = PsRetrieve(light_sensor_enabled_key, NULL, 0);
    if (ret_len)
    {
        PsRetrieve(light_sensor_enabled_key, &ret, requested_words);
        if (ret)
        {
            return TRUE;
        }
    }
#endif
    return FALSE;
}
